from typing import Optional
from app.service.storage.status import get_storage_statuser
from app.service.storage.nodestatus import get_node_statuser
from app.service.storage.scale import get_storage_scaler
from fastapi import APIRouter, Depends
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from app.controller.model.storage import AddStorageReq, AddStorageRes, DeleteStorageReq, ScaleStorageReq
from app.db import get_db
from app.service.storage import get_storage_creator, get_storage_deleter, get_storage_lister
from app.utils.response import BaseRes


storage_router = APIRouter()


@storage_router.post('/storage/add')
async def add_storage(req: AddStorageReq, db=Depends(get_db)):
    creator = get_storage_creator(
        db,
        req.storageType,
        storage_scale=req.storageScale,
        main_node_memory=req.mainNodeMemory,
        slave_node_memory=req.slaveNodeMemory
    )
    service_id = creator.create()

    return JSONResponse(content=jsonable_encoder(BaseRes(data=AddStorageRes(serviceID=service_id))))


@storage_router.get('/storage')
def get_storage_list(page: int = 1, size: int = 20, name: Optional[str] = None, db=Depends(get_db)):
    lister = get_storage_lister(
        db,
        page=page,
        size=size
    )

    res = lister.list()
    return JSONResponse(content=jsonable_encoder(BaseRes(data=res)))


@storage_router.post('/storage/del')
async def delete_storage(req: DeleteStorageReq, db=Depends(get_db)):
    deleter = get_storage_deleter(db, service_id=req.serviceID)
    deleter.delete()

    return JSONResponse(content=jsonable_encoder(BaseRes()))


@storage_router.get('/storage/status')
def get_storage_status(db=Depends(get_db)):
    statuser = get_storage_statuser(db)
    res = statuser.status()
    return JSONResponse(content=jsonable_encoder(BaseRes(data=res)))


@storage_router.get('/node/status')
def get_node_status(db=Depends(get_db)):
    statuser = get_node_statuser(db)
    res = statuser.status()
    return JSONResponse(content=jsonable_encoder(BaseRes(data=res)))


@storage_router.post('/storage/scale')
async def scale_storage(req: ScaleStorageReq, db=Depends(get_db)):
    scaler = get_storage_scaler(
        db, req.service_id,  req.storage_scale)
    res = scaler.scale()
    return JSONResponse(content=jsonable_encoder(BaseRes(data=res)))
